import path from 'node:path'
import ejs from 'ejs'
import fs from 'node:fs'
import fse from 'fs-extra'
import { fileURLToPath } from 'node:url'
import { program } from 'commander'
import assert from 'node:assert'

const __filename = fileURLToPath(import.meta.url)
const __dirname = path.join(path.dirname(__filename), '..')
const templateDir = path.join(__dirname, 'templates')

assert(fs.existsSync(templateDir), new Error(`template dir "${templateDir}" is not exists`))
assert(fs.statSync(templateDir).isDirectory(), new Error(`${templateDir} is not directory`))

program
  .argument('<name>', '组件名')
  .argument('<out>', '文件输出位置')
  .option('-t, --template <value>', '指定模板文件或目录', 'table-search')
  .option('-v, --vars [vars...]', '模板变量, 如: -v foo1=bar1 foo2=bar2 ...')
  .option('-e, --ext [ext]', '输出文件后缀', '.vue')
  .option('-f, --force', '覆盖写入')
  
program.parse()

const opts = program.opts()
const tplFiles = []
const vars = {}
const outDir = path.join(__dirname, 'src', 'views', program.args[1])

if (opts.vars instanceof Array && opts.vars.length) {
  opts.vars.forEach(i => {
    if (typeof i === 'string') {
      const [k, v] = i.trim().split('=').map(s => s.trim())
      vars[k] = v
    }
  })
}


const tPath = path.join(templateDir, opts.template)
assert(fs.existsSync(tPath), new Error(`template file "${tPath}" not found`))
const tStat = fs.statSync(tPath)

if (tStat.isDirectory()) {
  const files = fs.readdirSync(tPath)
  assert(files.length > 0, new Error(`template dir "${tPath}" is empty`))
  files.forEach(f => {
    const fileName = path.join(tPath, f)
    tplFiles.push({
      templateFile: fileName,
      template: fs.readFileSync(fileName, { encoding: 'utf-8' }),
      vars: { 
        ...vars, 
        templateFile: fileName,
        outDir, 
        ext: opts.ext,
        name: program.args[0]
      },
    })
  });
} else {
  tplFiles.push({
    template: fs.readFileSync(tPath, { encoding: 'utf-8' }),
    templateFile: tPath,
    vars: { 
      ...vars, 
      templateFile: tPath, 
      outDir, 
      ext: opts.ext,
      name: program.args[0]
    }
  })
}


tplFiles.forEach(({ template, vars }) => {
  const nameTpl = path.basename(vars.templateFile.replace(/.ejs$/, '')) + opts.ext
  const renderedName = path.join(vars.outDir, ejs.render(nameTpl.replace(/__(\S+)__/g, (...args) => {
    return `<%= ${args[1]}; %>`
  }), vars))
  const content = ejs.render(template, vars)
  const outParsed = path.parse(renderedName)
  if (!fs.existsSync(outParsed.dir)) {
    fse.mkdirpSync(outParsed.dir)
  }

  if (fs.existsSync(renderedName)) {
    assert(opts.force, new Error(`文件 "${renderedName}" 已存在, 如果需要强制覆盖可以添加 "-f" 或 "--force" 参数`))
    fs.renameSync(renderedName, renderedName + '.old')
  }
  fs.writeFileSync(renderedName, content, { encoding: 'utf-8' })
})
